﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.UI;
using YArchitech.HCLoad.Parameters;
using YArchitech.HCLoad.Utils;
using YArchitech.Revit;

namespace YArchitech.HCLoad.Annotate
{
	public class SpaceAnnotate
	{
		public SpaceAnnotate(UIApplication rvtUIAPP, SpaceAttributeFile spAttFile)
		{
			this.m_revitUIApp = rvtUIAPP;
			this.m_spAttFile = spAttFile;
			this.GetSpaces();
		}

		public ReadOnlyCollection<Level> Levels
		{
			get
			{
				return new ReadOnlyCollection<Level>(this.m_levels);
			}
		}

		private void GetSpaces()
		{
			Document document = this.m_revitUIApp.ActiveUIDocument.Document;
			FilteredElementIterator elementIterator = new FilteredElementCollector(document).OfClass(typeof(Level)).GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				Level level = element as Level;
				if (level != null)
				{
					this.m_levels.Add(level);
					this.m_spaceDictionary.Add(level.Id, new List<Space>());
				}
			}
			FilteredElementIterator elementIterator2 = new FilteredElementCollector(document).WherePasses(new SpaceFilter()).GetElementIterator();
			elementIterator2.Reset();
			while (elementIterator2.MoveNext())
			{
				Element element2 = elementIterator2.Current;
				Space space = element2 as Space;
				if (space != null && space.Location != null && null != space.ClosedShell && RevitVersionFuncs.GetGeometryObjectArray(space.ClosedShell).Count > 0)
				{
					this.m_spaceDictionary[space.LevelId].Add(space);
				}
			}
		}

		private bool BindingSpaceAnnotate(Space space, ElementId annoId)
		{
			try
			{
				space.GetParameter(SpaceSharedParameters.AnnotateParamName).Set(annoId.IntegerValue);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				return false;
			}
			return true;
		}

		public bool AnnotateAllSpace()
		{
			if (!SpaceSharedParameters.AddSpaceAnnotateParameter(this.m_revitUIApp))
			{
				return false;
			}
			bool revomeAnnotateText = !this.m_spAttFile.IsAnyItemChecked();
			Document document = this.m_revitUIApp.ActiveUIDocument.Document;
			try
			{
				Transaction transaction = new Transaction(document, "YArchitech_HCLoad_Annotate");
				transaction.Start();
				foreach (Level level in this.Levels)
				{
					foreach (Space space in this.m_spaceDictionary[level.Id])
					{
						this.AnnotateSpace(space, revomeAnnotateText);
					}
				}
				document.Regenerate();
				transaction.Commit();
			}
			catch (Exception ex)
			{
				ex.ToString();
				return false;
			}
			return true;
		}

		private static ViewPlan GetPlanform2DView(Space space)
		{
			IEnumerable<ViewPlan> source = from elem in new FilteredElementCollector(space.Document).OfClass(typeof(ViewPlan)).ToElements()
			let viewPlan = elem as Autodesk.Revit.DB.ViewPlan
			where viewPlan != null && !viewPlan.IsTemplate && viewPlan.GenLevel.Id.IntegerValue == space.LevelId.IntegerValue
			select viewPlan;
			if (source.Count<ViewPlan>() > 0)
			{
				return source.First<ViewPlan>();
			}
			return null;
		}

		public bool AnnotateSpace(Space space, bool revomeAnnotateText)
		{
			Document document = this.m_revitUIApp.ActiveUIDocument.Document;
			ViewPlan planform2DView = SpaceAnnotate.GetPlanform2DView(space);
			LocationPoint locationPoint = space.Location as LocationPoint;
			new UV(locationPoint.Point.X, locationPoint.Point.Y);
			Parameter parameter = space.GetParameter(SpaceSharedParameters.AnnotateParamName);
			if (parameter == null)
			{
				return false;
			}
			ElementId elementId = new ElementId(parameter.AsInteger());
			Element element = new YJKDocument(document).GetElement(elementId);
			if (element is TextNote)
			{
				if (revomeAnnotateText)
				{
					document.Delete(elementId);
					return true;
				}
				TextNote textNote = element as TextNote;
				if (textNote != null)
				{
					textNote.Text = this.GetSpaceAnnotateText(space);
				}
			}
			else
			{
				if (revomeAnnotateText)
				{
					return true;
				}
				XYZ xyz = new XYZ(1.0, 1.0, 0.0);
				XYZ origin = locationPoint.Point - xyz;
				XYZ viewDirection = planform2DView.ViewDirection;
				XYZ upDirection = planform2DView.UpDirection;
                double lineWidth = HcUnit.CovertToAPI(0.1, (DisplayUnitType)0);
                TextAlignFlags textAlign = (TextAlignFlags)576;
				string spaceAnnotateText = this.GetSpaceAnnotateText(space);
				TextNote textNote = document.GetTextNode(planform2DView, origin, viewDirection, upDirection, lineWidth, textAlign, spaceAnnotateText);
				this.BindingSpaceAnnotate(space, textNote.Id);
				ElementId id = textNote.Id;
			}
			return true;
		}

		private string GetSpaceAnnotateText(Space space)
		{
			if (space == null || this.m_spAttFile == null)
			{
				return "";
			}
			string text = "";
			foreach (SpaceAttributeGroup spaceAttributeGroup in this.m_spAttFile.Groups)
			{
				foreach (SpaceAttribute spaceAttribute in spaceAttributeGroup.Attributes)
				{
					if (spaceAttribute.Cheked)
					{
						Guid guid = new Guid(spaceAttribute.GUID);
						Parameter parameter = space.get_Parameter(guid);
						if (parameter != null)
						{
							string name = spaceAttribute.Name;
							string text2;
							if (HcUtils.IsEnglish)
							{
								if (name.Contains("Humidity Load"))
								{
									if (name.Contains("Humidity Load Density"))
									{
										text2 = parameter.AsDouble().ToString() + " kg/(h.m²)";
									}
									else
									{
										text2 = parameter.AsDouble().ToString() + " kg/h";
									}
								}
								else
								{
									text2 = parameter.AsValueString();
								}
							}
							else if (name.Contains("湿负荷"))
							{
								if (name.Contains("湿负荷指标"))
								{
									text2 = parameter.AsDouble().ToString() + " kg/(h.m²)";
								}
								else
								{
									text2 = parameter.AsDouble().ToString() + " kg/h";
								}
							}
							else
							{
								text2 = parameter.AsValueString();
							}
							if (string.IsNullOrEmpty(text2))
							{
								text2 = parameter.AsInteger().ToString();
							}
							string str = name + ":" + text2 + "\n";
							text += str;
						}
					}
				}
			}
			text.Trim();
			return text;
		}

		private UIApplication m_revitUIApp;

		private List<Level> m_levels = new List<Level>();

		private Dictionary<ElementId, List<Space>> m_spaceDictionary = new Dictionary<ElementId, List<Space>>();

		private Dictionary<Space, TextNote> m_spAnnoDictionary = new Dictionary<Space, TextNote>();

		private SpaceAttributeFile m_spAttFile;

		private bool m_bEn = HcUtils.IsEnglish;
	}
}
